package com.xtaller.sdboot.controller;

import com.alibaba.fastjson.JSONObject;
import com.xtaller.sdboot.entity.IamAccount;
import com.xtaller.sdboot.entity.IamRole;
import com.xtaller.sdboot.entity.IamUserApplication;
import com.xtaller.sdboot.entity.IamUserRole;
import com.xtaller.sdboot.service.*;
import com.xtaller.sdboot.util.PermissionUtil;
import com.xtaller.sdboot.core.R;
import com.xtaller.sdboot.utils.annotation.Permission;
import com.xtaller.sdboot.utils.annotation.Token;
import com.xtaller.sdboot.core.base.BaseController;
import com.xtaller.sdboot.core.base.BaseEntity;
import com.xtaller.sdboot.utils.helper.JsonHelper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/** 
* 代码生成 
* @author: Taller  
* @date: 2020-02-23 00:33:56
* @Description: 用户与应用关系中间表控制器 
*/ 
@Api(tags = "用户与应用关系中间表控制器") 
@RestController 
@RequestMapping("/v1/iam/user/application") 
public class IamUserApplicationController extends BaseController<IamUserApplication> {
    @Autowired private IamUserApplicationService userApplicationService;
    @Autowired private IamUserService userService;
    @Autowired private IamAccountService accountService;
    @Autowired private IamUserRoleService userRoleService;
    @Autowired private IamRoleService roleService;
    @Autowired private IamApplicationService appService;
    @Autowired private PermissionUtil permissionUtil;

    @ApiOperation("获取用户可用的应用")
    @Token
    @GetMapping("/toSelect")
    public Object getUserApplicationList(){
        var upQw = new QueryWrapper<IamUserApplication>();
        upQw.lambda().eq(IamUserApplication::getUserId, userId.get());
        var list = userApplicationService.getList(upQw);
        if(list.size() > 0) {
            var appIds = list.stream().map(x -> x.getAppId()).collect(Collectors.toList());
            var apps = appService.getByIds(appIds);
            var data = JsonHelper.list();
            if(apps.size() > 0){
                list.stream().forEach(x -> {
                    var opt = apps.stream().filter(y -> y.getId().equals(x.getAppId())).findFirst();
                    if(opt.isPresent()){
                        var object = JsonHelper.create("isDefault", 0)
                                .put("name", opt.get().getName())
                                .put("id", opt.get().getId())
                                .put("remark", opt.get().getRemark())
                                .put("panel", opt.get().getPanel())
                                .put("icon", opt.get().getIcon());
                        data.add(object);
                    }
                });
            }
            return R.ok(data);
        }
        return R.ok(list);
    }


    @ApiOperation("数据表格-用于配置管理员")
    @Permission(authorities = "iam:user:application:data:list")
    @Override
    public Object getByPage(HttpServletRequest request) throws Exception {
        return super.getByPage(request);
    }

    @ApiOperation("数据表格-用于应用管理用户")
    @Permission(authorities = "iam:user:platform:account:data:list")
    @GetMapping("/platform/account/list")
    public Object getByPageByPlatform(HttpServletRequest request) {
        request = setAppId(request);
        var params = convertParams2Map(request);
        var p = pageer(params);
        var qw = convertMap2Wrapper(params);
        var page = new Page<IamUserApplication>(p.getCurrent(), p.getLimit());
        var pageData = userApplicationService.pages(page, qw);
        var json = formatterTable(pageData);
        var list = JsonHelper.o2l(json.get("data"));

        // 数据处理
        if(list.size() > 0){
            var uids = list.stream().map(x -> x.getString("userId")).collect(Collectors.toList());
            var users = userService.getByIds(uids);
            // 加载角色信息
            var urQw = new QueryWrapper<IamUserRole>();
            urQw.lambda()
                    .eq(IamUserRole::getAppId, applicationId.get())
                    .in(IamUserRole::getUserId, uids);
            var urs = userRoleService.getList(urQw);
            List<IamRole> roles = new ArrayList<>();
            if(urs.size() > 0){
                var roleId = urs.stream().map(x -> x.getRoleId()).collect(Collectors.toList())
                                    .stream().distinct().collect(Collectors.toList());
                roles = roleService.getByIds(roleId);
            }

            var accountQw = new QueryWrapper<IamAccount>();
            accountQw.lambda()
                    .in(IamAccount::getUserId, uids)
                    .orderByDesc(BaseEntity::getCreateTime)
                    .orderByDesc(IamAccount::getUserId);
            var accounts = accountService.getList(accountQw);
            var data = JsonHelper.list();
            List<IamRole> finalRoles = roles;
            accounts.stream().forEach(x -> {
                var opt = users.stream().filter(y -> y.getId().equals(x.getUserId())).findFirst();
                if(opt.isPresent()){
                    var ua = list.stream().filter(y -> y.getString("userId").equals(x.getUserId())).findFirst();
                    var isAdmin = 0;
                    if(ua.isPresent()){
                        isAdmin = ua.get().getInteger("isAdmin");
                    }

                    // 读取角色信息
                    var userRoles = JsonHelper.list();
                    if(urs.size() > 0){
                        var ars = urs.stream().filter(y -> x.getUserId().equals(y.getUserId())).collect(Collectors.toList());
                        if(finalRoles.size() > 0){
                            ars.stream().forEach(y -> {
                                var r = finalRoles.stream().filter(z -> z.getId().equals(y.getRoleId())).findFirst();
                                if(r.isPresent()) {
                                    var ro = r.get();
                                    var ur = JsonHelper.create("name", ro.getName())
                                                .put("id", ro.getId())
                                                .put("value", ro.getId());
                                    userRoles.add(ur);
                                }
                            });
                        }
                    }

                    var account = JsonHelper.create("mobile", opt.get().getMobile())
                            .put("id", x.getId())
                            .put("isAdmin", isAdmin)
                            .put("role", userRoles)
                            .put("userId", x.getUserId())
                            .put("userType", x.getUserType())
                            .put("authType", x.getAuthType())
                            .put("authAccount", x.getAuthAccount())
                            .put("realName", x.getRealName())
                            .put("gender", x.getGender())
                            .put("openId", x.getOpenId())
                            .put("unionId", x.getUnionId())
                            .put("state", x.getState())
                            .put("createTime", x.getCreateTime());
                    data.add(account);
                }
            });

            json.put("data", data);
        }
        return json;
    }


    @ApiOperation("分配用户管理员")
    @Permission(authorities = "iam:user:application:opt:create")
    @Override
    public Object createEntity(@Valid @RequestBody IamUserApplication entity, HttpServletRequest request) throws Exception {
        return super.createEntity(entity, request);
    }

    @ApiOperation("管理员降权")
    @Permission(authorities = "iam:user:application:opt:delete")
    @DeleteMapping("/admin/{id}")
    public Object downAuth(@PathVariable("id") Serializable id, HttpServletRequest request) throws Exception {
        var model = new IamUserApplication();
        model.setIsAdmin(0);
        return super.updateEntity(id, model, request);
    }

    @Override
    protected JSONObject afterPage(JSONObject json) throws Exception {
        var list = JsonHelper.o2l(json.get("data"));
        if(list.size() > 0){
            var uids = list.stream().map(x -> x.getString("userId")).collect(Collectors.toList());
            var users = userService.getByIds(uids);
            if(users.size() > 0){
                list.stream().forEach(x -> {
                    x.put("user", JsonHelper.create());
                    var opt = users.stream().filter(y -> y.getId().equals(x.getString("userId"))).findFirst();
                    if(opt.isPresent()){
                        x.put("user", opt.get());
                    }
                });
            }
        }
        json.put("data", list);
        return super.afterPage(json);
    }

    @Override
    protected String beforeCreate(BaseEntity entity) throws Exception {
        var model = (IamUserApplication) entity;
        var qw = new QueryWrapper<IamUserApplication>();
        qw.lambda().eq(IamUserApplication::getUserId, model.getUserId())
                .eq(IamUserApplication::getAppId, model.getAppId());
        var list = userApplicationService.getList(qw);
        if(list.size() > 0){
            var object = list.get(0);
            if(object.getIsAdmin() == 0) {
                userApplicationService.delete(object.getId());
            }else {
                return "已经是应用管理员了";
            }
        }
        model.setIsAdmin(1);
        return super.beforeCreate(model);
    }

    @Override
    protected String afterCreated(BaseEntity entity) throws Exception {
        var model = (IamUserApplication) entity;
        permissionUtil.updateAppCache(model.getUserId(), model.getIsAdmin(), null);
        return super.afterCreated(entity);
    }

    @Override
    protected String beforeUpdate(BaseEntity entity) throws Exception {
        var model = (IamUserApplication) entity;
        permissionUtil.updateAppCache(model.getUserId(), model.getIsAdmin(), null);
        return super.beforeUpdate(entity);
    }
}
